<template>
    <div v-html="renderToHtml()" class="xui-markdown-body"></div>
</template>
<script lang="ts">
import { defineComponent, ref, watch } from 'vue'
import { marked } from 'marked'
import hljs from 'highlight.js'
import 'highlight.js/styles/foundation.css'

import katex from 'katex'
import 'katex/dist/katex.css'

export default defineComponent({
    props: {
        text: {
            type: String,
            default: ()=>('')
        }
    },
    setup(props){
        let mdText = ref<string>(props.text);
        
        const render = new marked.Renderer()
        const renderTex = (text: string) => {
            return katex.renderToString(text.replace(/&lt;/g, "<").replace(/&gt;/g, ">"));
        }         
        render.paragraph = (text: string) => {
            const isTeXInline     = /\$\$(.*)\$\$/g.test(text);
            const isTeXLine       = /^\$\$(.*)\$\$$/.test(text);
            let textRs = "";
            if (!isTeXLine && isTeXInline)
            {
                textRs = text.replace(/(\$\$([^\$]*)\$\$)+/g, ($1:string, $2:string) => {
                    return `<span class="md-tex">${ renderTex( $2.replace(/\$/g, ""))}</span>`;
                });
            }
            else
            {
                textRs = (isTeXLine) ? `<div class="md-tex"><div class="tex-box">${ renderTex( text.replace(/\$/g, ""))}</div></div>`  
                    :  `<p>${text}</p>\n`;
            }            
            return textRs;            
        }
        render.code = (code:string, lang:string, escaped: boolean) => {
            if(lang === "math"){
                return `<p class="md-tex">${ renderTex(code)}</p>`
            }
            console.log(lang)
            console.log(escaped)
            const hcoders = hljs.highlightAuto(code, [lang]);        
            return `<pre class="md-code"><code>${hcoders.value}</code></pre>`;
        }
        marked.setOptions({
            renderer: render,
            gfm: true, // github样式的markdown语法            
            pedantic: false, // 只解析markdown定义的，不修正markdown的错误
            sanitize: false, // 原始输出，忽略html标签，关闭后，可直接渲染html标签
            breaks: true,  // 允许回车换行。该选项要求 gfm 为true。
            highlight: (code, lang) => hljs.highlight(code, {language: lang }).value,
        })
        const renderToHtml = () => {
            return marked(mdText.value)
        }
        watch (()=>props.text, (newText, prevText)=> {
            mdText.value = newText            
        })
        return {
            mdText,            
            renderToHtml
        }
    }
})
</script>

<style lang="scss">
.xui-markdown-body {
    font-size: 14px;
    width: 90em;
    h1,h2,h3,h4,h5 {
        line-height: 2em;
    }
    h1 {
        font-size:  2em;
    }
    h2 {
        font-size: 1.8em;
    }
    h3 {
        font-size: 1.5em;
    }
    h4, h5 {
        font-size: 1em;
    }
    p {
        line-height: 2em;
    }
    div.md-tex { 
        display: flex;
        padding: 1em;
        > div.tex-box{        
            font-size: 1.3em;
            margin: 1em auto;
        }
    }
    ol > li > p ,ul > li > p {
        display: inline-block;
    }
    ol {
        list-style-position: inside;    
        line-height: 2em;    
        li {
            margin: 0 0.5em;
        }
    }
    ul {
        li {
            list-style: none;                               
            line-height: 2em;
            &:before {                
                content: '';
                display: inline-block;
                width: 0.6em;
                height: 0.6em;
                border-radius: 0.6em;
                background-color: #555;
                margin: 0 0.5em;
            }     
        }
    } 
    code {
        font-family: "JetBrainsMono";
        width: calc(100% - 4em);
        word-break: break-word;
        white-space: pre-wrap;
    }
    pre {
        background-color: #eee;
        padding: 1.5em 1em;
        border-radius: 10px;
        margin: 0.5em;
    }
    blockquote {
        padding: 0.5em 1em;        
        border-left: .25em solid #d0d7de;
    }
    table {
        display: block;
        width: 100%;
        width: max-content;
        max-width: 100%;
        overflow: auto;        
        border-spacing: 0;
        border-collapse: collapse;
        tr {
            background-color: #ffffff;
            border-top: 1px solid hsla(210,18%,87%,1);
        }
        th,td {
            padding: 6px 13px;
            border: 1px solid #d0d7de;
        }
        tr:nth-child(2n) {
            background-color: #f6f8fa;
        }
    }
    img {
        max-width: 100%;
    }


}
</style>